package net.ib.rpc.util;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * @(#)IBException.java 1.0 05/04/14 Copyright 2005 InfoBank Corporation. All
 *                      rights reserved. Exception 상속 최상위 Class
 * 
 * @author 류재훈 Service R&D Lab
 * @version 1.0
 * @since 05/04/14
 * @history
 */
public class IBException extends Exception {

	private static final long serialVersionUID = 1L;

	private java.lang.Throwable rootCause;

	private boolean isFirst = true;

	private String code = "9999";

	public String getCode() {
		return this.code;
	}

	/**
	 * 생성자
	 */
	public IBException() {
		super();
	}

	/**
	 * 특정한 메시지를 갖는 IBException을 생성한다.
	 * 
	 * @param s
	 *            메시지
	 */
	public IBException(String s) {
		super(s);
	}

	public IBException(String code, String message) {
		super(message);
		this.code = code;
	}

	/**
	 * 특정한 메시지와 Throwable을 갖는 IBException을 생성한다.
	 * 
	 * @param s
	 *            메시지
	 * @param rootCause
	 *            exception chaining에 필요한 Throwable
	 */
	public IBException(String message, Throwable rootCause) {
		super(message);
		this.rootCause = rootCause;
		this.isFirst = false;
	}

	/**
	 * 특정한 메시지와 Throwable을 갖는 IBException을 생성한다.
	 * 
	 * @param s
	 *            메시지
	 * @param rootCause
	 *            exception chaining에 필요한 Throwable
	 */
	public IBException(String code, String message, Throwable rootCause) {
		super(message);
		this.rootCause = rootCause;
		this.code = code;
		this.isFirst = false;
	}

	/**
	 * 특정한 Throwable을 갖는 IBException을 생성한다.
	 * 
	 * @param rootCause
	 *            exception chaining에 필요한 Throwable
	 */
	public IBException(Throwable rootCause) {
		this();
		this.rootCause = rootCause;
		this.isFirst = false;
	}

	/**
	 * LException의 rootCause를 리턴하는 메소드이다.
	 * 
	 * @return Throwable인 rootCause를 리턴
	 */
	public Throwable getRootCause() {
		return rootCause;
	}

	/**
	 * StackTrace를 찍는다.
	 * 
	 * @param newStackTrace
	 *            java.lang.String
	 */
	public static String getStackTrace(Throwable throwable) {
		boolean flag = false;

		if (flag) {
			StringWriter s = new StringWriter();
			PrintWriter pw = new PrintWriter(s);
			pw.println(" : getStackTrace() : =====PrintStackTrace=====");
			throwable.printStackTrace(pw);

			return s.toString();
		} else {
			return throwable.getMessage();
		}
	}

	/**
	 * Stack Trace를 string형태로 리턴하는 메소드이다.
	 * 
	 * @return Stack Trace를 string 형태로 리턴
	 */
	public String getStackTraceString() {
		StringWriter s = new StringWriter();
		printStackTrace(new PrintWriter(s));

		return s.toString();
	}

	/**
	 * Throwable과 exception chaining한 메시지의 stack trace
	 * 
	 * @see java.lang.Throwable
	 */
	public void printStackTrace() {
		printStackTrace(System.err);
	}

	/**
	 * 지정한 error output stream인 PrintStream에 출력한다.
	 * 
	 * @param PrintStream
	 * @see java.lang.Throwable
	 */
	public void printStackTrace(java.io.PrintStream s) {
		synchronized (s) {
			super.printStackTrace(s);

			if (rootCause != null) {
				rootCause.printStackTrace(s);
			}

			if (isFirst || !(rootCause instanceof IBException)) {
				s.println("-----------------------------");
			}
		}
	}

	/**
	 * 지정한 error output stream인 PrintWriter에 출력한다.
	 * 
	 * @param s
	 *            PrintWriter
	 * @see java.lang.Throwable
	 */
	public void printStackTrace(java.io.PrintWriter s) {
		synchronized (s) {
			super.printStackTrace(s);

			if (rootCause != null) {
				rootCause.printStackTrace(s);
			}

			if (isFirst || !(rootCause instanceof IBException)) {
				s.println("-----------------------------");
			}
		}
	}
}
